﻿#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

struct RouteEntry {
    std::string destination; // 目标网络
    std::string nextHop;     // 下一跳
    int metric;              // 距离（跳数）
};

// 打印路由表
void printRoutingTable(const std::vector<RouteEntry>& table) {
    std::cout << "Destination\tNext Hop\tMetric\n";
    for (const auto& entry : table) {
        std::cout << entry.destination << "\t\t" << entry.nextHop << "\t\t" << entry.metric << "\n";
    }
}

// RIP 更新算法
std::vector<RouteEntry> updateRoutingTable(const std::vector<RouteEntry>& r1, const std::vector<RouteEntry>& r2, const std::string& r2Address) {
    std::vector<RouteEntry> updatedTable = r1;

    for (const auto& r2Entry : r2) {
        bool found = false;

        for (auto& r1Entry : updatedTable) {
            if (r1Entry.destination == r2Entry.destination) {
                found = true;
                // 如果通过 R2 的路径更短，则更新
                if (r2Entry.metric + 1 < r1Entry.metric) {
                    r1Entry.metric = r2Entry.metric + 1;
                    r1Entry.nextHop = r2Address;
                }
                break;
            }
        }

        // 如果 R1 中没有该目标网络，则添加
        if (!found) {
            updatedTable.push_back({ r2Entry.destination, r2Address, r2Entry.metric + 1 });
        }
    }

    return updatedTable;
}

int main() {
    // 示例：R1 的初始路由表
    std::vector<RouteEntry> r1 = {
        {"192.168.1.0", "Direct", 1},
        {"192.168.2.0", "Direct", 1},
        {"192.168.3.0", "192.168.2.1", 2}
    };

    // 示例：R2 的路由表
    std::vector<RouteEntry> r2 = {
        {"192.168.3.0", "Direct", 1},
        {"192.168.4.0", "Direct", 1}
    };

    std::string r2Address = "192.168.2.1"; // R2 的地址

    std::cout << "R1 Initial Routing Table:\n";
    printRoutingTable(r1);

    std::cout << "\nR2 Routing Table:\n";
    printRoutingTable(r2);

    // 更新 R1 的路由表
    std::vector<RouteEntry> updatedR1 = updateRoutingTable(r1, r2, r2Address);

    std::cout << "\nR1 Updated Routing Table:\n";
    printRoutingTable(updatedR1);

    return 0;
}
